class vec2 {
  num x;
  num y;
  
  double get lengthSq() => x * x + y * y;
  double get length() => Math.sqrt(x * x + y * y);

  vec2(this.x, this.y);
  
  vec2.zero() {
    this.x = 0;
    this.y = 0;
  }
  
  vec2.one() {
    this.x = 1;
    this.y = 1;
  }
  
  vec2.from(vec2 other) {
    this.x = other.x;
    this.y = other.y;
  }

  double dot(vec2 other) {
    return x * other.x + y * other.y;
  }
  
  double distanceSq(vec2 other) {
    final num dx = x - other.x;
    final num dy = y - other.y;
    return Math.sqrt(dx * dx + dy * dy);
  }
  
  double distance(vec2 other) {
    return Math.sqrt(distanceSq(other));
  }
  
  void normalize() {
    double l = lengthSq;
    if (l != 0.0 && l != 1.0) {
      l = Math.sqrt(l);
      x /= l;
      y /= l;
    }
  }
  
  vec2 operator + (vec2 right) {
    return new vec2(x + right.x, y + right.y);
  }
  
  vec2 operator - (vec2 right) {
    return new vec2(x - right.x, y - right.y);
  }
  
  vec2 operator * (num right) {
    return new vec2(x * right, y * right);
  }
  
  vec2 operator / (num right) {
    return new vec2(x / right, y / right);
  }
}